
/////////////////////////
/////desinger: Dup
/***description: this module is a state to 
	control the 8 channel test results***/
module control(
	//input
	clk_1m,
	rst_n,
	jud_err,
	end_flag,
	time_out,
	up_link_req,
	wr_sram_done,
	init_resp_done,
    test_mode,//test_mode 1 represent the 8channel test
              //test_mode 0 represent the 4channel test
    time_20ms,
	//output
	oe_8ch,
	down_link_req,
	Result0,Result1,Result2,Result3,
	Result4,Result5,Result6,Result7,
	wr_sram_req,
	init_resp_req,
	sram_mux,
    ch_125k_en, //ch_125k_en to judge the enable 125ksignal ,11 represent 01234567  channel have signal
                                                                  //10 represent  1,3,5,7  channel have signal
                                                                  //01 represent  0,2,4,6  channel have signal 
    oe_timer
);
parameter N = 8;

input clk_1m,
	  rst_n;
input [N-1:0] jud_err;
input [N-1:0] end_flag;
input time_out;
input up_link_req;
input wr_sram_done;
input init_resp_done;
input test_mode;
input time_20ms;

output [7:0] oe_8ch;	
output down_link_req;
output [7:0]   Result0,Result1,Result2,Result3,
			   Result4,Result5,Result6,Result7;
output wr_sram_req;
output sram_mux;
output init_resp_req;	
output [1:0]ch_125k_en;   
output oe_timer	; 

parameter IDLE = 4'd0,               INIT_RESP = 4'd1,      WAIT_TEST = 4'd2,    PRE_TEST = 4'd3 ,    
		  EIGHT_TEST = 4'd4,    EIGHT_T_RESULT = 4'd5,    FOUR_TEST_L = 4'd6,  PRE_TEST2  = 4'd7 ,
          FOUR_TEST_H = 4'd8,    FOUR_T_RESULT = 4'd9,     WRITE_SRAM = 4'd10;			  		  
reg [7:0] oe_8ch_r;
reg down_link_req_r;
reg [3:0] state;
reg [3:0] nstate;	
reg [7:0] Result0_r,Result1_r,Result2_r,Result3_r,
		  Result4_r,Result5_r,Result6_r,Result7_r;
reg wr_sram_req_r;
reg init_resp_req_r;
reg [1:0] ch_125k_en_r;
reg oe_timer_r;



assign oe_8ch   = oe_8ch_r;	
assign down_link_req  = down_link_req_r;	
assign Result0 = Result0_r;
assign Result1 = Result1_r;
assign Result2 = Result2_r;
assign Result3 = Result3_r;
assign Result4 = Result4_r;
assign Result5 = Result5_r;
assign Result6 = Result6_r;
assign Result7 = Result7_r;
assign wr_sram_req = wr_sram_req_r;
assign sram_mux =  (state == IDLE || state == WAIT_TEST ||state == PRE_TEST || state == PRE_TEST2)  ;
   //sram_mux is 1 the up_link module use sram_ctrl ,otherwise the down_link module use sram_ctrl;


assign init_resp_req = init_resp_req_r;
assign ch_125k_en    = ch_125k_en_r;
assign   oe_timer    = oe_timer_r;


///////**************state machine********//////
always @(posedge clk_1m or negedge rst_n)
    if(rst_n == 1'b0)
	   state <= IDLE;
	else
	   state <= nstate;

always @(*)
if(rst_n ==	1'b0)
	nstate = IDLE;
else	
	case(state)
		    IDLE   : nstate = (up_link_req)    ? INIT_RESP   : IDLE;
		 INIT_RESP : nstate = (init_resp_done) ? WAIT_TEST   : INIT_RESP ;
         WAIT_TEST : nstate = (up_link_req)    ? PRE_TEST    : WAIT_TEST ;
         PRE_TEST  : nstate = (time_20ms) ?( test_mode ? EIGHT_TEST : FOUR_TEST_L ) : PRE_TEST ;
        EIGHT_TEST : nstate = (&end_flag || time_out) ? EIGHT_T_RESULT : EIGHT_TEST;
    EIGHT_T_RESULT : nstate =  WRITE_SRAM;
       FOUR_TEST_L : nstate = ((end_flag[0] & end_flag[2] & end_flag[4] & end_flag[6]) || time_out) ? PRE_TEST2 : FOUR_TEST_L;
        PRE_TEST2  : nstate = (time_20ms) ? FOUR_TEST_H : PRE_TEST2;
       FOUR_TEST_H : nstate = ((end_flag[1] & end_flag[3] & end_flag[5] & end_flag[7]) || time_out) ? FOUR_T_RESULT : FOUR_TEST_H ;
     FOUR_T_RESULT : nstate =  WRITE_SRAM;	
		WRITE_SRAM : nstate = (wr_sram_done ) ? (WAIT_TEST) : WRITE_SRAM ;  
		default    : nstate = IDLE;
	endcase
//******all test module oe enable signal******////
	always@(posedge clk_1m or negedge rst_n)
		if(rst_n == 1'b0)
			oe_8ch_r <= 8'd0;
		else if (state == EIGHT_TEST)
				oe_8ch_r <= 8'b1111_1111;
        else if (state == FOUR_TEST_L)
                oe_8ch_r <= 8'b0101_0101;
        else if (state == FOUR_TEST_H)
                oe_8ch_r <= 8'b1010_1010;
        else if (down_link_req)
                oe_8ch_r <= 8'b0000_0000;
        
	always@(posedge clk_1m or negedge rst_n)
		if(rst_n == 1'b0)
			ch_125k_en_r <= 2'b00;
		else if(state == PRE_TEST  && test_mode)
				ch_125k_en_r <= 2'b11;
        else if(state == PRE_TEST && !test_mode)
                ch_125k_en_r <= 2'b01;            
        else if (state == PRE_TEST2)
                ch_125k_en_r <= 2'b10;
        else if(down_link_req)
                 ch_125k_en_r <= 2'b00;//which to be debug


        
    always@(posedge clk_1m or negedge rst_n)
            if(rst_n == 1'b0)
                oe_timer_r  <= 1'b0;    
            else if (state == WAIT_TEST && up_link_req)
                oe_timer_r  <= 1'b1;
            else if (state == PRE_TEST && time_20ms)
                oe_timer_r  <= 1'b0;
            else if(state == EIGHT_TEST)
                oe_timer_r  <= 1'b1;
            else if(state == FOUR_TEST_L)
                oe_timer_r  <= 1'b1;
            else if(state == PRE_TEST && time_20ms)
                oe_timer_r  <= 1'b0; 
            else if(state == FOUR_TEST_H)
                oe_timer_r  <= 1'b1;
            else if(down_link_req)
                oe_timer_r  <= 1'b0;
		
//******state machine action******////
always@(posedge clk_1m or negedge rst_n)
	if(rst_n == 1'b0)
		begin
			down_link_req_r  <= 1'b0;
			wr_sram_req_r  <= 1'b0;
			Result0_r <= 1'b0;
			Result1_r <= 1'b0;
			Result2_r <= 1'b0;
			Result3_r <= 1'b0;
			Result4_r <= 1'b0;
			Result5_r <= 1'b0;
			Result6_r <= 1'b0;
			Result7_r <= 1'b0;
			init_resp_req_r <= 1'b0;
           
		end
	else case(state) 
		IDLE : 
			begin
				down_link_req_r  <= 1'b0;	
				  wr_sram_req_r  <= 1'b0;
			end
			
		INIT_RESP:	
		begin
			init_resp_req_r <= 1'b1;
			if(init_resp_done)
			begin
				init_resp_req_r  <= 1'b0;
				down_link_req_r  <= 1'b1;
				wr_sram_req_r    <= 1'b0;
			end
		end
        
        WAIT_TEST , PRE_TEST , EIGHT_TEST:
        begin
             down_link_req_r  <= 1'b0;	
               wr_sram_req_r  <= 1'b0;
        end        
        
             
		EIGHT_T_RESULT : 
		    begin	
		    // Result0_r <= (end_flag[0]) ? ((jud_err[0]) ? 8'h80:8'h00) : ( time_out ? 8'h80 : 8'h80 );
			// Result1_r <= (end_flag[1]) ? ((jud_err[1]) ? 8'h81:8'h01) : ( time_out ? 8'h81 : 8'h81 );
			// Result2_r <= (end_flag[2]) ? ((jud_err[2]) ? 8'h82:8'h02) : ( time_out ? 8'h82 : 8'h82 );
			// Result3_r <= (end_flag[3]) ? ((jud_err[3]) ? 8'h83:8'h03) : ( time_out ? 8'h83 : 8'h83 );
			// Result4_r <= (end_flag[4]) ? ((jud_err[4]) ? 8'h84:8'h04) : ( time_out ? 8'h84 : 8'h84 );
			// Result5_r <= (end_flag[5]) ? ((jud_err[5]) ? 8'h85:8'h05) : ( time_out ? 8'h85 : 8'h85 );
			// Result6_r <= (end_flag[6]) ? ((jud_err[6]) ? 8'h86:8'h06) : ( time_out ? 8'h86 : 8'h86 );
			// Result7_r <= (end_flag[7]) ? ((jud_err[7]) ? 8'h87:8'h07) : ( time_out ? 8'h87 : 8'h87 );
			
			///**************************debug the procedrue************************//////
			Result0_r <= (end_flag[0]) ? ((jud_err[0]) ? 8'h80:8'h00) : ( time_out ? 8'h99 : 8'haa );
			Result1_r <= (end_flag[1]) ? ((jud_err[1]) ? 8'h81:8'h01) : ( time_out ? 8'h99 : 8'haa );
			Result2_r <= (end_flag[2]) ? ((jud_err[2]) ? 8'h82:8'h02) : ( time_out ? 8'h99 : 8'haa );
			Result3_r <= (end_flag[3]) ? ((jud_err[3]) ? 8'h83:8'h03) : ( time_out ? 8'h99 : 8'haa );
			Result4_r <= (end_flag[4]) ? ((jud_err[4]) ? 8'h84:8'h04) : ( time_out ? 8'h99 : 8'haa );
			Result5_r <= (end_flag[5]) ? ((jud_err[5]) ? 8'h85:8'h05) : ( time_out ? 8'h99 : 8'haa );
			Result6_r <= (end_flag[6]) ? ((jud_err[6]) ? 8'h86:8'h06) : ( time_out ? 8'h99 : 8'haa );
			Result7_r <= (end_flag[7]) ? ((jud_err[7]) ? 8'h87:8'h07) : ( time_out ? 8'h99 : 8'haa ); 
			end
       
         
        FOUR_TEST_L:
            begin
                Result0_r <= (end_flag[0]) ? ((jud_err[0]) ? 8'h80:8'h00) : ( time_out ? 8'h99 : 8'haa );
                Result2_r <= (end_flag[2]) ? ((jud_err[2]) ? 8'h82:8'h02) : ( time_out ? 8'h99 : 8'haa );
                Result4_r <= (end_flag[4]) ? ((jud_err[4]) ? 8'h84:8'h04) : ( time_out ? 8'h99 : 8'haa );
                Result6_r <= (end_flag[6]) ? ((jud_err[6]) ? 8'h86:8'h06) : ( time_out ? 8'h99 : 8'haa );
            end
            
        PRE_TEST2:
         begin
             down_link_req_r  <= 1'b0;	
               wr_sram_req_r  <= 1'b0;
         end
          
        FOUR_TEST_H:
            begin
                Result1_r <= (end_flag[1]) ? ((jud_err[1]) ? 8'h81:8'h01) : ( time_out ? 8'h99 : 8'haa );
                Result3_r <= (end_flag[3]) ? ((jud_err[3]) ? 8'h83:8'h03) : ( time_out ? 8'h99 : 8'haa );
                Result5_r <= (end_flag[5]) ? ((jud_err[5]) ? 8'h85:8'h05) : ( time_out ? 8'h99 : 8'haa );
                Result7_r <= (end_flag[7]) ? ((jud_err[7]) ? 8'h87:8'h07) : ( time_out ? 8'h99 : 8'haa ); 
            end          
        FOUR_T_RESULT:
            begin
                Result0_r <= Result0_r;
                Result1_r <= Result1_r;
                Result2_r <= Result2_r;
                Result3_r <= Result3_r;
                Result4_r <= Result4_r;
                Result5_r <= Result5_r;
                Result6_r <= Result6_r;
                Result7_r <= Result7_r;
            end
		WRITE_SRAM:
		begin
			  wr_sram_req_r <= 1'b1;
			if(wr_sram_done)
			begin
				down_link_req_r  <= 1'b1;
				wr_sram_req_r    <= 1'b0;
			end
		end
		
		default :
			begin
				down_link_req_r  <= 1'b0;	
				  wr_sram_req_r  <= 1'b0;
			end
		endcase
endmodule